package org.net.cms.service.parentaccount;

import jakarta.annotation.Resource;
import org.net.cms.controller.app.application.vo.AppApplicationReqVO;
import org.net.cms.controller.app.parentccount.vo.AppUpdatePasswordReqVO;
import org.net.cms.dao.ApplicationDto;
import org.net.cms.dao.ParentAccountDto;
import org.net.cms.dao.StudentDto;
import org.net.cms.enums.StudentApplicationEnums;
import org.net.cms.mapper.ApplicationMapper;
import org.net.cms.mapper.ParentAccountMapper;
import org.net.cms.mapper.StudentMapper;
import org.springframework.security.core.Authentication;
import org.springframework.security.core.context.SecurityContextHolder;
import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;
import org.springframework.security.crypto.bcrypt.BCryptPasswordEncoder;
import org.springframework.security.crypto.password.PasswordEncoder;
import org.springframework.stereotype.Service;

import java.util.List;

@Service
public class ParentAccountServiceImpl implements ParentAccountService, UserDetailsService {

    @Resource
    private ParentAccountMapper parentAccountMapper;

    @Resource
    private StudentMapper studentMapper;

    @Resource
    private ApplicationMapper applicationMapper;

    @Override
    public ParentAccountDto getParentAccountDto(int id) {
        return parentAccountMapper.getParentAccountById(id);
    }

    @Override
    public List<ParentAccountDto> parentAccountList() {
        return parentAccountMapper.getParentAccountList();
    }

    @Override
    public Boolean deleteParentAccountDto(int id) {
        parentAccountMapper.deleteParentAccount(id);
        return true;
    }

    @Override
    public Boolean resumePassword(int id) {
        String parentCardId = parentAccountMapper.getParentAccountById(id).getParentCardId();
        String newPassword = parentCardId.substring(parentCardId.length() - 6);
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        parentAccountMapper.resumePassword(id, passwordEncoder.encode(newPassword));
        return Boolean.TRUE;
    }

    @Override
    public Boolean updatePassword(AppUpdatePasswordReqVO updatePasswordReqVO) {
        // 1. 获取当前认证的 Authentication 对象
        Authentication authentication = SecurityContextHolder.getContext().getAuthentication();
        UserDetails userDetails = (UserDetails) authentication.getPrincipal();
        String phone = userDetails.getUsername();

        String oldEncode = parentAccountMapper.getOldPasswordByPhone(phone);
        // 如果旧密码不正确
        BCryptPasswordEncoder encoder = new BCryptPasswordEncoder();
        // 匹配旧密码和旧密码的密文是不是一致的
        if (!encoder.matches(updatePasswordReqVO.getOldPassword(), oldEncode)) {
            // 不一致
            return Boolean.FALSE;
        }
        // 将新密码设置为密文
        PasswordEncoder passwordEncoder = new BCryptPasswordEncoder();
        String newEncode = passwordEncoder.encode(updatePasswordReqVO.getNewPassword());
        // 通过电话号码获取用户id
        int id = parentAccountMapper.getParentAccountByPhone(phone).getId();
        // 更改密码
        parentAccountMapper.resumePassword(id, newEncode);
        return Boolean.TRUE;
    }

    @Override
    public Boolean submitUnbindStudent(String phone, int studentId) {
        StudentDto student = studentMapper.getStudent(studentId);
        // 判断申请表中是否存在当前申请
        ApplicationDto isUnbind = applicationMapper.selectUnbindApplication(phone, student.getStudentCardId());
        if (isUnbind != null) {
            return Boolean.FALSE;
        }
        // 提交审核申请表
        AppApplicationReqVO applicationReqVO = getAppApplicationReqVO(student);
        applicationMapper.addAdmissionApplication(applicationReqVO);
        return Boolean.TRUE;
    }

    // 回填审核信息
    private static AppApplicationReqVO getAppApplicationReqVO(StudentDto student) {
        AppApplicationReqVO applicationReqVO = new AppApplicationReqVO();
        applicationReqVO.setParentCardId(student.getParentCardId());
        applicationReqVO.setParentPhone(student.getParentPhone());
        applicationReqVO.setStudentCardId(student.getStudentCardId());
        applicationReqVO.setName(student.getName());
        applicationReqVO.setSex(student.getSex());
        applicationReqVO.setBirthday(student.getBirthday());
        applicationReqVO.setDomicile(student.getDomicile());
        applicationReqVO.setStatus(StudentApplicationEnums.UNBIND_PENDING_APPROVAL.getStatus());
        return applicationReqVO;
    }

    @Override
    public UserDetails loadUserByUsername(String username) throws UsernameNotFoundException {
        ParentAccountDto byPhone = parentAccountMapper.getParentAccountByPhone(username);
        if (byPhone == null) {
            throw new UsernameNotFoundException(username);
        } else {
            UserDetails userDetails = org.springframework.security.core.userdetails.User.builder()
                    .username(byPhone.getPhone())
                    .password(byPhone.getPassword())
                    .build();
            return userDetails;
        }
    }
}
